package org.to_zero.ssm.sdm.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.to_zero.ssm.sdm.entity.vo.ResponseEntity;
import org.to_zero.ssm.sdm.util.GetBeanUtil;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @Author to_zero
 * @Description //TODO 业务切面
 * @Date 16:12 2020/11/23
 */
@Component
@Aspect
public class ServiceAspect {

    /**
     * 对multiQuery进行进行增强,添加数据条数至响应体
     *
     * @param pjp 连接点
     * @return 响应体
     * @throws Throwable
     */
    @Around("execution(* org.to_zero.ssm.sdm.service.impl..find*(..))")
    public Object fillQueryDataCount(ProceedingJoinPoint pjp) throws Throwable {
        ResponseEntity entity = null;
        Object[] args = pjp.getArgs();
        Class<?> pojoClass = args[0].getClass();
        Object proceed = pjp.proceed(args);
        if (proceed instanceof ResponseEntity) {
            Object target = pjp.getTarget();
            Class<?> invokeClass = target.getClass();
            Field[] fields = invokeClass.getDeclaredFields();
            for (Field field : fields) {
                if (field.getName().endsWith("Mapper")) {
                    field.setAccessible(true);
                    Class<?> mapperClass = field.getType();
                    Object bean = GetBeanUtil.getBean(mapperClass);
                    String fqn = pjp.toString();
                    int start = fqn.lastIndexOf(".")+ 1;
                    int end = fqn.lastIndexOf("(");
                    String targetMethodName = fqn.substring(start,end);
                    Method method = mapperClass.getDeclaredMethod(targetMethodName.concat("Count"), pojoClass);
                    method.setAccessible(true);
                    Integer count = (Integer) method.invoke(bean, args[0]);
                    entity = (ResponseEntity) proceed;
                    entity.put(ResponseEntity.COUNT_TAG, count);
                    break;
                }
            }
        }
        return entity;
    }
}